import org.apache.lucene.document.Field
import org.apache.lucene.document.Document
import org.springframework.orm.hibernate3.SessionFactoryUtils
import org.springframework.transaction.support.TransactionTemplate
import org.springframework.transaction.support.TransactionCallback
class IndexProcess implements Runnable {
    def entry
    def indexService
    def nameEntityService
    def sessionFactory
    def transactionManager
    public void run() {
        def txTemplate = new TransactionTemplate(transactionManager)
        txTemplate.execute({
            entry = sessionFactory.currentSession.merge(entry)
            if (entry.indexed) {
                indexService.removeIndex(entry.id.toString())
            }
            def idField = new Field("id",
                                    entry.id.toString(), Field.Store.YES,
                                    Field.Index.UN_TOKENIZED)
            def titleField = new Field("title",
                                       entry.title, Field.Store.NO,
                                       Field.Index.TOKENIZED)
            // remove all tag from content
            def content = entry.content.replaceAll("<[^<]+>", '')
            def contentField = new Field("content",
                                         content, Field.Store.NO,
                                         Field.Index.TOKENIZED,
                                         Field.TermVector.YES)
            def doc = new Document()
            doc.add(idField)
            doc.add(titleField)
            doc.add(contentField)
            def nameEntities = nameEntityService.extract(entry.content)
            nameEntities.each {
              def fieldName = it.type.toString()
              def field = new Field(fieldName,
                                    it.name,
                                    Field.Store.YES,
                                    Field.Index.UN_TOKENIZED)
              doc.add(field)
            }
            if (entry.tags) {
              def tagList = entry.tags.split(',')
              tagList.each {
                def field = new Field('tag',
                                      it,
                                      Field.Store.YES,
                                      Field.Index.UN_TOKENIZED)
                doc.add(field)
              }
              // special field that store tokenize tags
              if (tagList) {
                def field = new Field('tags',
                                      entry.tags,
                                      Field.Store.NO,
                                      Field.Index.TOKENIZED)
                doc.add(field)
              }
            }
            // field for resource id (use in exclude, include feature)
            def resourceId = entry.resource.id
            doc.add(new Field('resourceId',
                              resourceId.toString(),
                              Field.Store.YES,
                              Field.Index.UN_TOKENIZED))
            indexService.index(doc)
            entry.indexed = true
            if (entry.validate()) {
                Entry.withTransaction {status ->
                    entry.save()
                }
            } else {
                entry.errors.allErrors.each {
                    log.error it
                }
            }

        } as TransactionCallback)
    }
}